package com.jd.org.service.impl;

import com.jd.basic.exception.BusinessException;
import com.jd.basic.exception.ErrorCode;
import com.jd.basic.service.impl.BaseServiceImpl;
import com.jd.org.domain.Department;
import com.jd.org.mapper.DepartmentMapper;
import com.jd.org.service.IDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


@Service
// 查询的方法比较多，使用查询的事务配置
// 只读，事务传播机制=SUPPORTS，有我就用，没有事务就不用
// @Inherited 在@Transactional有这个注解表示可以被继承，而@Service不能被继承，子类必须写
@CacheConfig(cacheNames = "dept") // 统一配置
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements IDepartmentService {

    @Autowired
    private DepartmentMapper departmentMapper;

    @Override
    @Transactional
    @CacheEvict(key = "'tree'") // 删除缓存
    public void add(Department department) {
        departmentMapper.add(department);
        String myDir = "/" + department.getId();
        String parDir = null;
        if (department.getParentId() != null) {
            Department parDept = departmentMapper.findOne(department.getParentId());
            parDir = parDept.getDirPath();

        }
        if (parDir != null) {
            department.setDirPath(parDir + myDir);
        }
        departmentMapper.update(department);
    }

    @Override
    @Transactional
    @CacheEvict(key = "'tree'") // 删除缓存
    public void update(Department department) {
        //
        if (department.getId() == department.getParentId()) {
            throw new BusinessException(ErrorCode.DEPT_PARENT_ERROR.getMessage());
        }
        String myDir = "/" + department.getId();
        String parDir = null;
        if (department.getParentId() != null) {
            Department parDept = departmentMapper.findOne(department.getParentId());
            parDir = parDept.getDirPath();

        }
        if (parDir != null) {
            department.setDirPath(parDir + myDir);
        }
        departmentMapper.update(department);
    }

    @Override
    @Transactional
    @CacheEvict(key = "'tree'") // 删除缓存
    public void del(Long id) {
        departmentMapper.del(id);
    }


    @Override
    @Transactional
    @CacheEvict(key = "'tree'") // 删除缓存
    public void patchDel(Long[] ids) {
        departmentMapper.patchDel(ids);
    }

    @Override
    @Cacheable(key = "'tree'") // 写入缓存
    public List<Department> deptTree() {
        return getDeptTree();
    }

    private ArrayList<Department> getDeptTree() {
        // 查询所有部门
        List<Department> all = departmentMapper.findAll();
        // 创建一个空map用id-部门表示部门
        HashMap<Long, Department> map = new HashMap<>();
        // 对部门进行遍历放入map
        for (Department department : all) {
            map.put(department.getId(), department);
        }
        // 创建一个集合用来存部门树
        ArrayList<Department> deptTree = new ArrayList<>();
        // 遍历判断如果没有上级部门即为顶级部门，直接放入
        for (Department department : all) {
            if (department.getParentId() == null) {
                deptTree.add(department);
            } else { // 不是顶级部门，查找上级部门
                Long parentId = department.getParentId();
                // 找到父部门，将自己放入上级部门的children中
                Department parentDepartment = map.get(parentId);
                parentDepartment.getChildren().add(department);
            }
        }
        return deptTree;
    }

}
